package cn.js189.uqc.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.js189.common.constants.Constants;
import cn.js189.common.constants.ErrorConstants;
import cn.js189.common.domain.ReqInfo;
import cn.js189.common.domain.RespHead;
import cn.js189.common.domain.RespInfo;
import cn.js189.common.util.Utils;
import cn.js189.common.util.exception.BaseAppException;
import cn.js189.common.util.exception.ExceptionUtil;
import cn.js189.common.util.helper.UUIDHelper;
import cn.js189.uqc.common.WxService;
import cn.js189.uqc.domain.invoice.InvoiceDetail;
import cn.js189.uqc.mapper.CheckInfoMapper;
import cn.js189.uqc.redis.RedisOperation;
import cn.js189.uqc.service.IWxInterService;
import cn.js189.uqc.service.InvoiceService;
import cn.js189.uqc.service.PubAddressIpervice;
import cn.js189.uqc.task.WxAuthTask;
import cn.js189.uqc.task.WxCardTask;
import cn.js189.uqc.util.HttpClientHelperForEop;
import cn.js189.uqc.util.UqcAddressCodeConstants;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j
@Service
public class WxInterServiceImpl implements IWxInterService {
	
	@Resource
	private WxService wxService;
	@Resource
	private CheckInfoMapper checkInfoMapper;
	@Resource
	private RedisOperation redisOperation;
	@Resource
	private InvoiceService invoiceService;
	@Resource
	private PubAddressIpervice pubAddressIpervice;
	
	@Override
	public String getInvoiceAuthTask(String reqParams) {
		// 查询授权情况单独起个定时任务
		try {
			ExecutorService executorService = Executors.newSingleThreadExecutor();
			WxAuthTask task = new WxAuthTask(wxService, checkInfoMapper, redisOperation);
			executorService.execute(task);
			executorService.shutdown();
			
		} catch (Exception e) {
			return "fail";
		}
		return "ok";
	}

	@Override
	public String inserWxCardTask(String reqParams) {
		try {
			
			ExecutorService executorService = Executors.newSingleThreadExecutor();
			WxCardTask task = new WxCardTask(wxService, checkInfoMapper, redisOperation);
			executorService.execute(task);
			executorService.shutdown();
			
		} catch (Exception e) {
			return "fail";
		}
		return "ok";
	}
	
	@Override
	public String checkBatchAuthInfo(String reqParams) {
		RespInfo responseJson = new RespInfo();
		RespHead responseHead = new RespHead();
		responseJson.setHead(responseHead);
		String tranId = "";
		JSONObject response;
		
		try {
			ReqInfo reqInfo = BeanUtil.toBean(reqParams, ReqInfo.class);
			JSONObject body = reqInfo.getBody();
			String partyId = body.getString("partyId");
			String appId = body.getString(Constants.APP_ID);
			String source = body.getString(Constants.SOURCE);
			
			String result = this.wxService.checkBatchAuthInfo(partyId, appId, source);
			JSONObject rspBody = JSON.parseObject(result);
			
			response = Utils.dealSuccessRespWithMsgAndStatus(responseHead, tranId, rspBody, "success", "00", responseJson);
			
			return response.toString();
		} catch (BaseAppException e) {
			response = Utils.dealBaseAppExceptionResp(responseHead, tranId, responseJson, e.getMsg(), e.getCode());
			log.debug("(查询微信一次授权状态) BaseAppException :{}", e.getMessage());
			return response.toString();
		} catch (Exception e) {
			response = Utils.dealExceptionResp(responseHead, tranId, responseJson);
			log.debug("(查询微信一次授权状态) Exception :{}", e.getMessage());
			return response.toString();
		}
	}
	
	@Override
	public String getWxAuthUrl(String reqParams) {
		
		log.debug("获取微信授权页入参: {}", reqParams);
		RespInfo responseJson = new RespInfo();
		RespHead responseHead = new RespHead();
		String tranId = "";
		JSONObject response;
		
		try {
			
			ReqInfo reqInfo = BeanUtil.toBean(reqParams, ReqInfo.class);
			JSONObject body = reqInfo.getBody();
			
			String money = body.getString("money");
			String source = body.getString(Constants.SOURCE);
			String type = body.getString("type");   // 申请开票类型
			String redirectUrl = body.getString("redirectUrl"); // 授权页后跳转链接
			
			// 申请开票类型授权,定时任务刷新状态进行插卡操作? 暂不做 2019-07-30
			if (StringUtils.equals("0", type)) {
				
				// 必须传跳转链接,否则无法填写抬头等信息
				if (StringUtils.isEmpty(redirectUrl)) {
					ExceptionUtil.throwBusiException(ErrorConstants.WX_GET_AUTH_URL_PARAM_ERROR);
				}
				
				// 生成ticketId 模拟订单id 获取授权页链接
				String ticketId = UUIDHelper.getUUID();
				JSONObject rspBody = this.wxService.getAuthUrl(ticketId, null, money, source, type, redirectUrl);
				
				response = Utils.dealSuccessRespWithMsgAndStatus(responseHead, tranId, rspBody, "success", "00", responseJson);
				return response.toString();
				
			}
			
			// 公众号领取发票类型授权,开票历史入口
			if (StringUtils.equals("2", type)) {
				
				String invoiceId = body.getString(Constants.INVOICE_ID);
				
				// 必须传发票实例id
				if (StringUtils.isEmpty(invoiceId)) {
					ExceptionUtil.throwBusiException(ErrorConstants.WX_GET_AUTH_URL_PARAM_ERROR);
				}
				
				InvoiceDetail invoiceDetail = invoiceService.selectInvoiceById(invoiceId);
				
				// 发票信息不存在
				if (null == invoiceDetail) {
					ExceptionUtil.throwBusiException(ErrorConstants.INVOICE_NOT_EXISTS);
					return "";
				}
				
				String invoiceMoney = invoiceDetail.getMoney();
				String tax = invoiceDetail.getTax();
				String totalMoney = String.valueOf(Integer.parseInt(invoiceMoney) - Integer.parseInt(tax));
				
				// 传入金额校验
				if (!StringUtils.equals(money, totalMoney)) {
					ExceptionUtil.throwBusiException(ErrorConstants.INVOICE_MONEY_ERROR);
				}
				
				// 根据发票实例id获取授权页链接
				JSONObject rspBody = this.wxService.getAuthUrl(null, invoiceId, money, source, type, redirectUrl);
				
				response = Utils.dealSuccessRespWithMsgAndStatus(responseHead, tranId, rspBody, "success", "00", responseJson);
				return response.toString();
				
			}
			
			// 一次授权
			if (StringUtils.equals("once", type)) {
				
				String partyId = body.getString("partyId");
				
				if (StringUtils.isEmpty(partyId)) {
					ExceptionUtil.throwBusiException(ErrorConstants.WX_GET_AUTH_URL_PARAM_ERROR);
				}
				
				String appId = body.getString(Constants.APP_ID);
				
				// appId必填
				if (StringUtils.isEmpty(appId)) {
					ExceptionUtil.throwBusiException(ErrorConstants.WX_GET_AUTH_URL_PARAM_ERROR);
				}
				
				JSONObject rspBody = this.wxService.getBatchAuthUrl(appId, partyId, source, redirectUrl);
				
				response = Utils.dealSuccessRespWithMsgAndStatus(responseHead, tranId, rspBody, "success", "00", responseJson);
				return response.toString();
				
			}
			
			response = Utils.dealSuccessRespWithMsgAndStatus(responseHead, tranId, null, "不支持的授权类型", ErrorConstants.WX_GET_AUTH_TYPE_NOT_SUPPORT, responseJson);
			return response.toString();
			
		} catch (BaseAppException e) {
			response = Utils.dealBaseAppExceptionResp(responseHead, tranId, responseJson, e.getMsg(), e.getCode());
			log.debug("获取微信授权页 BaseAppException {}", e.getMessage());
			return response.toString();
		} catch (Exception e) {
			response = Utils.dealExceptionResp(responseHead, tranId, responseJson);
			log.debug("获取微信授权页 Exception :{}", e.getMessage());
			return response.toString();
		}
	}
	
	@Override
	public String getZnwInfo(String reqParams) {
		log.debug("智能网查询接口 input :{}", reqParams);
		RespInfo responseJson = new RespInfo();
		RespHead responseHead = new RespHead();
		responseJson.setHead(responseHead);
		String tranId = "";
		JSONObject response;
		try {
			ReqInfo reqInfo = BeanUtil.toBean(reqParams, ReqInfo.class);
			JSONObject body = reqInfo.getBody();
			String accNum = body.getString("accNum");
			
			JSONObject reqJson = new JSONObject();
			reqJson.put("accNum", accNum);
			String reqString = JSON.toJSONString(reqJson);
			String url = pubAddressIpervice.getActionUrl(UqcAddressCodeConstants.ZNW_INFO_URL,reqInfo.getHead().getLoginNbr());
			log.debug("智能网查询入参:{}", reqString);
			String res = HttpClientHelperForEop.postToBill(url, reqString, "");
			log.debug("智能网查询出参:{}", res);
			if (CharSequenceUtil.isNotBlank(res)) {
				JSONObject resBody = JSON.parseObject(res);
				response = Utils.dealSuccessRespWithMsgAndStatus(responseHead, tranId, resBody, "success", "00", responseJson);
			} else {
				response = Utils.dealExceptionRespWithMsgAndStatus(responseHead, tranId, Constants.ERR_INF_NULL, "97", responseJson);
			}
			return response.toString();
		}catch (Exception e) {
			response = Utils.dealExceptionResp(responseHead, tranId, responseJson);
			log.debug("智能网查询接口 Exception {}", e.getMessage());
			return response.toString();
		}
	}
}
